package com.wisewin.circle.service;

import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.wisewin.circle.config.dto.ResultDTO;
import com.wisewin.circle.config.dto.ResultDTOBuilder;
import com.wisewin.circle.system.Constants;
import com.wisewin.circle.util.JedisUtil;
import com.wisewin.circle.util.WxUtil;
import com.wisewin.circle.util.env.Env;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.client.RestTemplate;
import java.util.HashMap;
import java.util.Map;

@Service
@Transactional
public class WechatAuthService {
    public final static Logger log = LoggerFactory.getLogger(WechatAuthService.class);

    @Autowired
    private RestTemplate restTemplate;

    // 获取openId
    public ResultDTO getOpenId(String code, String appId, String appSecret) {
        if (StringUtils.isEmpty(code) || StringUtils.isEmpty(appId) || StringUtils.isEmpty(appSecret)) {
            return ResultDTOBuilder.failure("1", "参数有误", null);
        }
        // 获取token
        String url = String.format("https://api.weixin.qq.com/sns/jscode2session?appid=%s&secret=%s&js_code=%s&grant_type=authorization_code",
                appId, appSecret, code);
        JSONObject result = JSON.parseObject(HttpUtil.get(url));
        if (result == null || result.get("openid") == null) {
            return ResultDTOBuilder.failure("1", "获取openId失败", null);
        }
        String openId = result.get("openid").toString();
        return ResultDTOBuilder.success(openId);
    }

    // 获取微信手机号码
    public ResultDTO getPhoneNumber(String code, String appId) {
        if (StringUtils.isEmpty(code) || StringUtils.isEmpty(appId)) {
            return ResultDTOBuilder.failure("1", "参数有误", null);
        }
        try {
            String accessToken = getAccessToken(appId, Env.getProperty("wechatAppSecret"));
            // 使用前端code获取手机号码 参数为json格式
            String url = "https://api.weixin.qq.com/wxa/business/getuserphonenumber?access_token=" + accessToken;
            Map<String, String> paramMap = new HashMap<>();
            paramMap.put("code", code);
            HttpHeaders headers = new HttpHeaders();
            HttpEntity<Map<String, String>> httpEntity = new HttpEntity<>(paramMap, headers);
            ResponseEntity<String> response = restTemplate.postForEntity(url, httpEntity, String.class);
            log.info("appId：" + appId + "，getPhoneNumber返回值信息：" + response.getBody());
            JSONObject phoneData = JSON.parseObject(response.getBody());
            if (phoneData == null || !"0".equals(phoneData.get("errcode").toString())) {
                return ResultDTOBuilder.failure("1", "获取手机号失败", null);
            }
            JSONObject phoneInfo = JSON.parseObject(phoneData.get("phone_info").toString());
            Object phone = phoneInfo.get("phoneNumber");
            return ResultDTOBuilder.success(phone);
        } catch (Exception e) {
            return ResultDTOBuilder.failure("1", "获取手机号失败", null);
        }
    }

    // 获取accessToken
    public static String getAccessToken(String appId, String appSecret) {
        // 从redis中获取accessToken
        String accessToken = JedisUtil.get("accessToken" + appSecret);
        if (accessToken == null) {
            // 获取token
            String token_url = String.format("https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=%s&secret=%s", appId, appSecret);
            JSONObject token = JSON.parseObject(HttpUtil.get(token_url));
            if (token == null) {
                return null;
            }
            accessToken = token.getString("access_token");
            // 存入redis
            JedisUtil.setEx("accessToken" + appId, accessToken, Constants.ONE_HOUR_LONG);
        }
        return accessToken;
    }
}
